package com.musemun.service.function.functionimpl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.musemun.common.ResultCode;
import com.musemun.config.Listener.OutBatchListener;
import com.musemun.exception.ApiException;
import com.musemun.pojo.*;
import com.musemun.pojo.Vo.CrLendVo;
import com.musemun.pojo.Vo.PagingVo;
import com.musemun.service.CrifoService;
import com.musemun.service.CrlendifoService;
import com.musemun.service.CropifoService;
import com.musemun.service.LendcontactService;
import com.musemun.service.function.LendContact;
import com.musemun.service.impl.CrifoServiceImpl;
import com.musemun.service.impl.CrlendifoServiceImpl;
import com.musemun.service.impl.CropifoServiceImpl;
import com.musemun.service.impl.LendcontactServiceImpl;
import com.musemun.util.ExcelUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.io.InputStream;
import java.util.Date;
import java.util.List;

/**
 * @description:
 *   外借类
 * @author winner
 * @date 2020/4/19
 */
@Service
public class LendContactImpl implements LendContact {
    //文物表操作字段
    @Resource
    private CropifoService cropifoService;

    public void setCropifoService(CropifoService cropifoService) {
        this.cropifoService = cropifoService;
    }

    //外借联系人操作表
    @Resource
    private LendcontactService lendcontactService;
    //文物外借详情字段
    @Resource
    private CrlendifoService crlendifoService;

    @Resource
    private CrifoService crifoService;





    public void setLendcontactService(LendcontactService lendcontactService) {
        this.lendcontactService = lendcontactService;
    }


    public void setCrlendifoService(CrlendifoService crlendifoService) {
        this.crlendifoService = crlendifoService;
    }

    public CrLendVo findById(long crNo) {
        LambdaQueryWrapper<Crlendifo> lambdaQuery = new QueryWrapper<Crlendifo>().lambda();
        lambdaQuery.eq(Crlendifo::getCrNo, crNo).orderByDesc(Crlendifo::getLSDate);
        List<Crlendifo> crlendifo = crlendifoService.list(lambdaQuery);
        if (crlendifo == null || crlendifo.size() == 0) {
            throw new ApiException(ResultCode.DATA_NULL, "编号" + String.valueOf(crNo) + "： 无此文物");
        }
        CrLendVo crLendVo = new CrLendVo();
        crLendVo.setCrlendifo(crlendifo.get(0));
        return crLendVo;
    }

    private Crlendifo _findById(long crNo) {
        LambdaQueryWrapper<Crlendifo> lambdaQuery = new QueryWrapper<Crlendifo>().lambda();
        lambdaQuery.eq(Crlendifo::getCrNo, crNo).orderByDesc(Crlendifo::getLSDate);
        List<Crlendifo> crlendifo = crlendifoService.list(lambdaQuery);
        if (crlendifo == null || crlendifo.size() == 0) {
            throw new ApiException(ResultCode.DATA_NULL, "编号" + String.valueOf(crNo) + "： 无此文物");
        }
        return crlendifo.get(0);
    }

    public PagingVo findByName(String name, int pageNum, int pageSize) {
        PagingVo pagingVo = new PagingVo();
        QueryWrapper<Crlendifo> lambdaQuery = new QueryWrapper<Crlendifo>();
        lambdaQuery.eq("LCName",name);
        if (pageNum == 0 && pageSize == 0) {
            pagingVo.setList(crlendifoService.list(lambdaQuery));
        } else {
            Page<Crlendifo> page = new Page<>(pageNum, pageSize);
            IPage<Crlendifo> iPage = crlendifoService.page(page, lambdaQuery);
            pagingVo.setList(iPage.getRecords());
            pagingVo.setNum(iPage.getTotal());
        }
        if (pagingVo.getList() == null) {
            throw new ApiException(ResultCode.DATA_NULL, "未找到任何信息");
        }
        return pagingVo;
    }

    public PagingVo selectAll(int pageNum, int pageSize) {
        PagingVo pagingVo = new PagingVo();
        LambdaQueryWrapper<Crlendifo> lambdaQuery = new QueryWrapper<Crlendifo>().lambda();
        if (pageNum == 0 && pageSize == 0) {
            pagingVo.setList(crlendifoService.list(lambdaQuery));
        } else {
            Page<Crlendifo> page = new Page<>(pageNum, pageSize);
            IPage<Crlendifo> iPage = crlendifoService.page(page, lambdaQuery);
            pagingVo.setList(iPage.getRecords());
            pagingVo.setNum(iPage.getTotal());
        }
        if (pagingVo.getList() == null) {
            throw new ApiException(ResultCode.DATA_NULL, "未找到任何信息");
        }
        return pagingVo;
    }





    @Transactional
    public boolean insert(Crlendifo crlendifo, Lendcontact lendcontact, Cropifo cropifo) {
        Crifo crifo = crifoService.getById(crlendifo.getCrNo());
        if (crifo == null) {
            throw new ApiException(ResultCode.GREENHOUSE_NOT_FOUND, "编号 " + String.valueOf(crlendifo.getCrNo()) + " 无此文物");
        }
        if (!crifo.getCrState().equals("在馆") && !crifo.getCrState().equals("入库")) {
            throw new ApiException(ResultCode.GREENHOUSE_NOT_FOUND, "编号 " + String.valueOf(crlendifo.getCrNo()) + " 文物不在馆");
        }
        if (crlendifo.getCrNo().longValue() != cropifo.getCrNo().longValue() || !crlendifo.getLCName().equals(lendcontact.getLCName())) {

            throw new ApiException(ResultCode.DATA_ERROR, "数据不一致");
        }
        if (lendcontactService.getById(lendcontact.getLCName()) == null) {
            if (!lendcontactService.save(lendcontact)) {
                throw new ApiException(ResultCode.ERROR, "插入外借联系人行时错误");
            }
        }
        if (!crlendifoService.save(crlendifo)) {
            throw new ApiException(ResultCode.ERROR, "插入外借信息行时错误");
        }
        Employee employee = cropifoService.getEmployee();
        cropifo.setENo(employee.getENo());
        if (!cropifoService.save(cropifo)) {
            throw new ApiException(ResultCode.ERROR, "插入操作行时错误");
        }

        UpdateWrapper<Crifo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("crNo", crlendifo.getCrNo());
        crifo.setCrState(cropifo.getOpType());
        if (!crifoService.update(crifo, updateWrapper)) {
            throw new ApiException(ResultCode.ERROR, "修改文物状态失败");
        }
        return true;
    }

    @Transactional
    public boolean delete(long crNo) {
        Crlendifo crlendifo = this._findById(crNo);
        LambdaQueryWrapper<Crlendifo> lambdaQuery1 = new QueryWrapper<Crlendifo>().lambda();
        lambdaQuery1.eq(Crlendifo::getCrNo, crNo);
        if (!crlendifoService.remove(lambdaQuery1)) {
            throw new ApiException(ResultCode.ERROR, "删除外借信息行时错误");
        }


        return true;
    }

    public CrLendVo update(long crNo) {
        Crlendifo crlendifo = this._findById(crNo);
        Lendcontact lendcontact = lendcontactService.getById(crlendifo.getLCName());
        if (lendcontact == null) {
            throw new ApiException(ResultCode.DATA_NULL, "没有找到记录");
        }
        CrLendVo crLendVo = new CrLendVo();
        crLendVo.setCrlendifo(crlendifo);
        crLendVo.setLendcontact(lendcontact);
        return crLendVo;
    }

    @Transactional
    public boolean update(Crlendifo crlendifo, Lendcontact lendcontact) {
        if (!crlendifo.getLCName().equals(lendcontact.getLCName())) {
            throw new ApiException(ResultCode.DATA_ERROR, "信息不一致");
        }
        if (!lendcontactService.saveOrUpdate(lendcontact)) {
            throw new ApiException(ResultCode.ERROR, "修改外借联系人时失败");
        }
        if (!crlendifoService.updateById(crlendifo)) {
            throw new ApiException(ResultCode.ERROR, "修改外借信息行时失败");
        }
        return true;
    }

    /**
     * 根据外借时间查询
     * 1： 查询小于lefttime
     * 2： 查询lefttime-righttime之间
     * 3： 查询大于lefttime
     * @param leftTime
     * @param rightTime
     * @param operate
     * @return
     */
    public List<Crlendifo> findByTime(Date leftTime, Date rightTime, int operate) {
        QueryWrapper<Crlendifo> lambdaQuery = new QueryWrapper<Crlendifo>();
        if (operate == 1) {
            lambdaQuery.lt("LSDate", leftTime);
        } else if (operate == 2) {
            if (rightTime == null) {
                throw new ApiException(ResultCode.DATA_ERROR, "参数rightTime错误");
            }
            lambdaQuery.between("LSDate", leftTime, rightTime);
        } else if (operate == 3){
            lambdaQuery.gt("LSDate", leftTime);
        } else {
            throw new ApiException(ResultCode.DATA_ERROR, "参数operate错误");
        }
        List<Crlendifo> list = crlendifoService.list(lambdaQuery);
        if (list == null) {
            throw new ApiException(ResultCode.DATA_NULL, "没有找到数据");
        }
        return list;
    }

    @Transactional
    public boolean insertBatch(InputStream inputStream) {
        try{
            EasyExcel.read(inputStream, OutExcel.class, new OutBatchListener(this)).sheet().doRead();
        } catch (ApiException e) {
            throw new ApiException(ResultCode.EXCELDATA_ERROR, e.getData());
        } catch (Exception e) {
            throw new ApiException(ResultCode.EXCELDATA_ERROR);
        }
//                  EasyExcel.read(inputStream, OutExcel.class, new OutBatchListener(this)).sheet().doRead();

        return true;
    }
}
